package com.ferry.config.client.loader;

import com.fasterxml.jackson.core.type.TypeReference;
import com.ferry.config.client.enumValue.Env;
import com.ferry.config.client.monitor.ConfigMonitor;
import com.ferry.config.client.util.JsonUtil;
import com.ferry.config.client.vo.GetData;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

/**
 * 长轮询 增量拉取
 * Created by daiyong
 */
public class LongPollConfigLoader extends AbstractConfigLoader {

	private static final Logger LOGGER = LoggerFactory.getLogger(LongPollConfigLoader.class);

	private ExecutorService executorService = Executors.newFixedThreadPool(1, new ThreadFactory() {
		public Thread newThread(Runnable r) {
			Thread t = Executors.defaultThreadFactory().newThread(r);
			t.setName("fconfig-http-long-poll");
			return t;
		}
	});

	public LongPollConfigLoader(String namespace, String env, ConfigMonitor configMonitor) {
		super(configMonitor, namespace, env);
	}

	@Override
	public void start() {
		initHttp();
		executorService.submit(new LongPollTask());
	}

	class LongPollTask implements Runnable {
		@Override
		public void run() {
			while (true) {
				try {

					List<GetData> getDatas = doLongPoll();
					//触发变更 异步
					configMonitor.fillConfigRepository(getDatas);

				} catch (Exception e) {
					LOGGER.error("LongPollTask.run Exception", e);
				}
			}
		}

		private List<GetData> doLongPoll(){

			CloseableHttpResponse response = null;
			Env envEnum = Env.lookUp(env);
			try {
				HttpPost post = new HttpPost(envEnum.getLongPollUrl());
				List<NameValuePair> parameters = new ArrayList<NameValuePair>(0);
				parameters.add(new BasicNameValuePair("nameSpace", namespace));
				parameters.add(new BasicNameValuePair("maxUtime", String.valueOf(configMonitor.getConfigMaxUtime())));

				System.out.println("long poll namespace:" + namespace + " maxUtime:" + String.valueOf(configMonitor.getConfigMaxUtime()));

				// 构造一个form表单式的实体
				UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters);
				// 将请求实体设置到httpPost对象中
				post.setEntity(formEntity);
				response = httpClient.execute(post);

				if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_MODIFIED) {
					//没有变化
				} else {
					if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
						String result = EntityUtils.toString(response.getEntity(), "UTF-8");
						if (StringUtils.isNotBlank(result)) {
							List<GetData> getDatas = JsonUtil.fromJson(result, new TypeReference<List<GetData>>() {
							});
							return getDatas;
						}
					}
				}

			} catch (Exception e) {
				LOGGER.error("doLongPoll Exception", e);
			}  finally {
				try {
					if (response != null) {
						response.close();
					}
				} catch (IOException e) {
					//ignore
				}
			}

			return null;
		}
	}

}
